import React, { useState, useRef, useCallback, useEffect } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Upload,
  CheckCircle,
  Loader2,
  Download,
  X,
  FileSpreadsheet,
  AlertCircle,
} from "lucide-react";
import { toast } from "@/components/ui/use-toast";
import { CrossingPointAPI } from "@/api/CrossingPoint";

// 常量定义 - 集中管理可配置项
const FILE_TYPES = {
  ALLOWED_EXTENSIONS: [".xlsx", ".xls", ".csv"],
  MIME_TYPES: [
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "application/vnd.ms-excel",
    "text/csv",
  ],
  TEMPLATE_NAME: "跨越点导入模板.xlsx",
};

export default function ExeUploadModal({
  isOpen,
  onClose,
  projectId,
  onImportSuccess,
  projects = [],
}) {
  // 状态管理
  const [file, setFile] = useState(null);
  const [fileDataList, setFileDataList] = useState([]);
  const [selectedItems, setSelectedItems] = useState([]); // 选中的项ID集合
  const [processingError, setProcessingError] = useState(null);
  const [currentStep, setCurrentStep] = useState("idle");
  const [isDragActive, setIsDragActive] = useState(false);
  const [isDownloading, setIsDownloading] = useState(false);
  const inputRef = useRef(null);

  // 当fileDataList变化时，默认全选
  useEffect(() => {
    if (fileDataList.length > 0) {
      // 假设每项有唯一标识id，如果没有可使用索引
      setSelectedItems(
        fileDataList.map((item) => item.id ?? fileDataList.indexOf(item))
      );
    } else {
      setSelectedItems([]);
    }
  }, [fileDataList]);

  // 清理错误状态 - 提取为独立函数
  const clearError = useCallback(() => {
    setProcessingError(null);
  }, []);

  // 验证文件类型
  const isValidFile = useCallback((file) => {
    if (!file) return false;
    const fileName = file.name.toLowerCase();
    return FILE_TYPES.ALLOWED_EXTENSIONS.some((ext) => fileName.endsWith(ext));
  }, []);

  // 处理文件选择 - 优化逻辑和错误处理
  const handleFileSelect = useCallback(
    async (files) => {
      if (!files || files.length === 0) return;

      clearError();
      const selectedFile = files[0];

      if (!isValidFile(selectedFile)) {
        setProcessingError(
          `文件类型不支持。请上传 ${FILE_TYPES.ALLOWED_EXTENSIONS.join(
            "、"
          )} 表格文件。`
        );
        setFile(null);
        return;
      }

      try {
        // 显示处理状态
        setCurrentStep("uploading");

        // 处理文件
        const response = await CrossingPointAPI.import(selectedFile);
        setFileDataList(response.data);
        setFile(selectedFile);

        // 提示信息优化
        if (file) {
          toast({
            title: "文件已替换",
            description: `已将文件替换为: ${selectedFile.name}`,
          });
        } else {
          toast({
            title: "文件已解析",
            description: `已解析文件: ${selectedFile.name}，共${response.data.length}条数据`,
          });
        }

        setCurrentStep("idle");
      } catch (error) {
        console.error("文件处理失败:", error);
        setProcessingError(`文件处理失败: ${error.message || "未知错误"}`);
        setFile(null);
        setCurrentStep("idle");
      }
    },
    [file, isValidFile, clearError]
  );

  // 移除选中的文件
  const handleRemoveFile = useCallback(() => {
    setFile(null);
    setFileDataList([]);
    setSelectedItems([]);
    clearError();
    if (inputRef.current) {
      inputRef.current.value = "";
    }
    toast({
      title: "已移除文件",
      description: "可以重新选择文件",
    });
  }, [clearError]);

  // 处理全选/取消全选
  const handleSelectAll = useCallback(() => {
    if (selectedItems.length === fileDataList.length) {
      setSelectedItems([]);
    } else {
      setSelectedItems(
        fileDataList.map((item) => item.id ?? fileDataList.indexOf(item))
      );
    }
  }, [selectedItems.length, fileDataList]);

  // 处理单个项选择
  const handleSelectItem = useCallback((id) => {
    setSelectedItems((prev) =>
      prev.includes(id) ? prev.filter((itemId) => itemId !== id) : [...prev, id]
    );
  }, []);

  // 拖拽事件处理 - 使用useCallback优化性能
  const handleDrag = useCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

  const handleDragIn = useCallback(
    (e) => {
      handleDrag(e);
      if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
        if (e.dataTransfer.items.length > 1) {
          setProcessingError("只能上传一个文件，请选择单个文件");
        } else {
          clearError();
        }
        setIsDragActive(true);
      }
    },
    [handleDrag, clearError]
  );

  const handleDragOut = useCallback(
    (e) => {
      handleDrag(e);
      setIsDragActive(false);
    },
    [handleDrag]
  );

  const handleDrop = useCallback(
    (e) => {
      handleDrag(e);
      setIsDragActive(false);

      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
        if (e.dataTransfer.files.length > 1) {
          setProcessingError("只能上传一个文件，请选择单个文件");
          toast({
            title: "文件数量超限",
            description: "每次只能上传一个文件",
            variant: "destructive",
          });
          return;
        }
        handleFileSelect(e.dataTransfer.files);
        e.dataTransfer.clearData();
      }
    },
    [handleDrag, handleFileSelect]
  );

  // 输入框文件变更处理
  const handleInputChange = useCallback(
    (e) => {
      e.preventDefault();
      if (e.target.files && e.target.files.length > 0) {
        if (e.target.files.length > 1) {
          setProcessingError("只能上传一个文件，请选择单个文件");
          toast({
            title: "文件数量超限",
            description: "每次只能上传一个文件",
            variant: "destructive",
          });
          if (inputRef.current) {
            inputRef.current.value = "";
          }
          return;
        }
        handleFileSelect(e.target.files);
      }
    },
    [handleFileSelect]
  );

  // 处理文件上传 - 增加加载状态和回调
  const handleUpload = useCallback(async () => {
    if (selectedItems.length === 0 || !projectId) return;

    // 获取选中的数据项
    const selectedData = fileDataList.filter((item, index) => {
      const itemId = item.id ?? index;
      return selectedItems.includes(itemId);
    });

    try {
      setCurrentStep("uploading");
      await CrossingPointAPI.importData(projectId, selectedData);
      setCurrentStep("success");
      toast({
        title: "上传成功",
        description: `已成功导入 ${selectedData.length} 条数据`,
      });
      // 通知父组件上传成功
      onImportSuccess && onImportSuccess();
    } catch (error) {
      console.error("文件上传失败:", error);
      setProcessingError(`上传失败: ${error.message || "未知错误"}`);
      setCurrentStep("idle");
    }
  }, [selectedItems, projectId, fileDataList, onImportSuccess]);

  // 下载模板文件 - 优化错误处理
  const handleDownloadTemplate = useCallback(async () => {
    if (isDownloading) return;

    try {
      setIsDownloading(true);
      const response = await CrossingPointAPI.importTemplate();

      // 验证响应类型
      const blob = new Blob([response], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      });

      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = FILE_TYPES.TEMPLATE_NAME;
      document.body.appendChild(a);
      a.click();

      // 清理资源
      setTimeout(() => {
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      }, 100);

      toast({
        title: "模板下载成功",
        description: FILE_TYPES.TEMPLATE_NAME,
      });
    } catch (error) {
      console.error("模板下载失败:", error);
      setProcessingError(`模板下载失败: ${error.message || "未知错误"}`);
    } finally {
      setIsDownloading(false);
    }
  }, [isDownloading]);

  // 重置状态并关闭弹窗
  const resetState = useCallback(() => {
    setFile(null);
    setFileDataList([]);
    setSelectedItems([]);
    setProcessingError(null);
    setCurrentStep("idle");
    setIsDragActive(false);
    if (inputRef.current) {
      inputRef.current.value = "";
    }
    onClose && onClose();
  }, [onClose]);

  // 渲染选中的文件信息
  const renderSelectedFile = () => {
    if (!file) return null;

    return (
      <div className="mt-2 flex items-center justify-between p-1 bg-gray-50 rounded-md">
        <div className="flex items-center">
          <FileSpreadsheet className="h-5 w-5 mr-2 text-primary" />
          <span className="text-sm truncate max-w-[200px]">{file.name}</span>
          <span className="ml-2 text-xs text-gray-500">
            {(file.size / 1024).toFixed(1)} KB
          </span>
        </div>
        <Button
          variant="ghost"
          size="sm"
          onClick={handleRemoveFile}
          className="h-7 w-7 p-0 text-gray-500 hover:text-red-500"
          aria-label="移除文件"
        >
          <X className="h-4 w-4" />
        </Button>
      </div>
    );
  };

  // 渲染数据列表
  const renderDataList = () => {
    if (fileDataList.length === 0) return null;

    // 获取数据项的表头（取第一条数据的键）
    const headers =
      fileDataList.length > 0
        ? Object.keys(fileDataList[0]).filter((key) => key !== "id") // 排除id字段
        : [];

    return (
      <div className=" border rounded-lg overflow-hidden">
        {/* 表头 */}
        <div className="flex items-center bg-gray-50 p-3 border-b">
          <div className="w-12">
            <Checkbox
              checked={
                selectedItems.length === fileDataList.length &&
                fileDataList.length > 0
              }
              onCheckedChange={handleSelectAll}
              aria-label="全选"
            />
          </div>
          <div className="flex-1 font-medium">数据列表</div>
        </div>

        {/* 列表内容：设置最大高度，超过出现滚动条 */}
        <div className="max-h-[200px] overflow-y-auto">
          {" "}
          {/* 关键：max-h 控制最大高度，overflow-y 控制滚动 */}
          {fileDataList.map((item, index) => {
            const itemId = item.id ?? index;
            const isSelected = selectedItems.includes(itemId);

            return (
              <div
                key={itemId}
                className={`flex items-center p-3 border-b last:border-0 ${
                  isSelected ? "bg-primary/5" : ""
                }`}
              >
                <div className="w-12">
                  <Checkbox
                    checked={isSelected}
                    onCheckedChange={() => handleSelectItem(itemId)}
                    aria-label={`选择第${index + 1}条数据`}
                  />
                </div>
                <div className="flex-1 grid grid-cols-3 gap-4 px-1 text-sm">
                  <div className="truncate">
                    <span className="text-gray-500">跨越对象:</span>
                    <span className="ml-1 font-medium">{item.crossingObject || "-"}</span>
                  </div>
                  <div className="truncate">
                    <span className="text-gray-500">跨越对象类型:</span>
                    <span className="ml-1 font-medium">
                      {item.crossingTypeText || "-"}
                    </span>
                  </div>
                  <div className="truncate">
                    <span className="text-gray-500">跨越点编号:</span>
                    <span className="ml-1 font-medium">{item.code || "-"}</span>
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* 选择统计 */}
        <div className="bg-gray-50 p-3 border-t text-sm text-gray-600">
          已选择{" "}
          <span className="font-medium text-primary">
            {selectedItems.length}
          </span>{" "}
          条，共 {fileDataList.length} 条
        </div>
      </div>
    );
  };

  // 渲染不同步骤的内容
  const renderContent = () => {
    switch (currentStep) {
      case "idle":
        return (
          <div className="grid gap-4 py-2">
            <Button
              variant="outline"
              onClick={handleDownloadTemplate}
              disabled={isDownloading || currentStep === "uploading"}
              className="w-full"
            >
              <Download className=" h-3 w-4" />
              下载导入模板（Excel格式）
            </Button>

            <div
              onDragEnter={handleDragIn}
              onDragLeave={handleDragOut}
              onDragOver={handleDrag}
              onDrop={handleDrop}
              className={`border-2 border-dashed rounded-lg p-6 transition-all duration-200 ${
                isDragActive
                  ? "border-primary/50 bg-primary/5"
                  : file
                  ? "border-primary bg-primary/5"
                  : "border-gray-300 hover:border-primary/50"
              }`}
            >
              <Input
                ref={inputRef}
                id="file-upload"
                type="file"
                accept={FILE_TYPES.MIME_TYPES.join(",")}
                onChange={handleInputChange}
                className="hidden"
                multiple={false}
              />

              {file ? (
                renderSelectedFile()
              ) : (
                <label
                  htmlFor="file-upload"
                  className="cursor-pointer flex flex-col items-center justify-center w-full h-full text-center"
                >
                  <div className="flex flex-col items-center justify-center pt-5 pb-6">
                    <FileSpreadsheet className="h-10 w-10 mb-3 text-gray-400" />
                    <p className="mb-2 text-sm text-gray-600">
                      <span className="font-semibold">点击上传文件</span>{" "}
                      或拖放文件至此处
                    </p>
                    <p className="text-xs text-gray-500">
                      支持 {FILE_TYPES.ALLOWED_EXTENSIONS.join("、")} 格式
                    </p>
                  </div>
                </label>
              )}
            </div>

            {/* 显示数据列表 */}
            {file && renderDataList()}

            {processingError && (
              <Alert variant="destructive">
                <AlertCircle className="h-4 w-4" />
                <AlertTitle>操作出错</AlertTitle>
                <AlertDescription>{processingError}</AlertDescription>
              </Alert>
            )}
          </div>
        );

      case "success":
        return (
          <div className="py-8 text-center">
            <Alert className="mb-6">
              <CheckCircle className="h-4 w-4 text-green-500" />
              <AlertTitle>上传成功</AlertTitle>
              <AlertDescription>
                已成功导入 {selectedItems.length} 条数据。
              </AlertDescription>
            </Alert>
          </div>
        );

      case "uploading":
        return (
          <div className="py-12 text-center">
            <Loader2 className="h-8 w-8 mx-auto text-primary animate-spin mb-4" />
            <p className="font-medium text-gray-700">正在处理文件...</p>
            <p className="text-sm text-gray-500 mt-2">
              这可能需要一些时间，请耐心等待。
            </p>
          </div>
        );

      default:
        return null;
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={resetState}>
      <DialogContent className="sm:max-w-[768px]">
        {" "}
        {/* 加宽弹窗以适应列表展示 */}
        <DialogHeader>
          <DialogTitle>上传表格文件</DialogTitle>
          <DialogDescription>
            请先下载模板，按照模板格式填写数据后，上传文件进行导入。
          </DialogDescription>
        </DialogHeader>
        <div>{renderContent()}</div>
        <DialogFooter>
          <Button
            variant="outline"
            onClick={resetState}
            disabled={currentStep === "uploading"}
          >
            取消
          </Button>

          {currentStep === "idle" && (
            <Button
              onClick={handleUpload}
              disabled={
                !file ||
                selectedItems.length === 0 ||
                currentStep === "uploading"
              }
            >
              <Upload className="mr-2 h-4 w-4" />
              开始上传
            </Button>
          )}

          {currentStep === "success" && (
            <Button onClick={resetState}>完成</Button>
          )}

          {currentStep === "uploading" && (
            <Button disabled>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              正在处理...
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
